package com.hy.mydesktop.shared.persistence.domain.gxt;


import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import net.sf.gilead.annotations.ServerOnly;

import org.hibernate.annotations.IndexColumn;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import com.extjs.gxt.ui.client.core.FastMap;
import com.extjs.gxt.ui.client.core.FastSet;
import com.extjs.gxt.ui.client.data.BeanModelTag;
import com.google.gwt.user.client.rpc.GwtTransient;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.hy.mydesktop.shared.persistence.domain.gxt.constant.GxtMetaModelTypeEnum;
import com.hy.mydesktop.shared.persistence.domain.gxt.constant.MetaDataConstants;
import com.hy.mydesktop.shared.persistence.domain.gxt.constant.MetaDataConstants;
import com.hy.mydesktop.shared.persistence.domain.util.Persistable;


/**
 * 
 * <ul>
 * <li>开发作者：花宏宇</li>
 * <li>设计日期：2012-2-5；时间：下午04:38:15</li>
 * <li>类型名称：GxtComponentMetaModel</li>
 * <li>设计目的： GxtComponentMetaModel存储的逻辑结构为：以GxtComponentControllerMetaNodeModel为节点的树形结构；<br>
 * 存储结构为：以GxtComponentControllerMetaNodeModel为元素的线性表；</li>
 * <li>类属性及方法说明：<br> 
 * getList():  用于存储以GxtComponentControllerMetaNodeModel为元素的线性表<br>
 * add(gxtComponentControllerMetaNodeModel):  为线性表，添加一个元素<br>
 * getControllerMetaModelId():  获取GxtComponentControllerMetaModel的Id<br>
 * getModels():忘记了用处<br>
 * indexOf(gxtComponentControllerMetaNodeModel):  获取gxtComponentControllerMetaNodeModel在线性表的位序<br>
 * getNextNode(gxtComponentControllerMetaNodeModel):  获取gxtComponentControllerMetaNodeModel在线性表中的下一个元素<br>
 * GxtComponentMetaModel迟绑定：gxtMetaModelTypeEnum用于判断GxtComponentMetaModel是属于BaseModel还是
 * 其子类TreeModel</li>
 * </ul>
 * <ul>
 * <b>修订编号：</b>
 * <li>修订日期：</li>
 * <li>修订作者：</li>
 * <li>修订原因：</li>
 * <li>修订内容：</li>
 * </ul>
 */
@Entity()
@Table(name="t_gxt_Component_Controller_MetaModel")
//public class GxtComponentControllerMetaModel  implements IsSerializable,Persistable{//,BeanModelTag{
public class GxtComponentControllerMetaModel  extends MyBaseModel{
	
	

	
	

	private static final long serialVersionUID = -3200875449903626439L;

	public GxtComponentControllerMetaModel() {
		super();
		if (getList()==null) {
			setList(new LinkedList<GxtComponentControllerMetaNodeModel>());
		}
	}
	
	public GxtComponentControllerMetaModel(List<GxtComponentControllerMetaNodeModel> list) {
		super();
		this.setList(list);
		// TODO Auto-generated constructor stub
	}

	public GxtComponentControllerMetaModel(Map<String, Object> properties) {
		
		super(properties);
		if (getList()==null) {
			setList(new LinkedList<GxtComponentControllerMetaNodeModel>());
		}
	}

	/**
	 * 嵌套集合为结构，存放的树形结构：以先序遍历排序内部元素
	 */
//	private String id;
//	private String controllerMetaModelId;
//	private List<GxtComponentControllerMetaNodeModel> list = new ArrayList<GxtComponentControllerMetaNodeModel>();
	//@GwtTransient
//	private Set<GwtRpcModel> models = new HashSet<GwtRpcModel>();
//	private Set<GxtComponentControllerMetaNodeModel> list = new HashSet<GxtComponentControllerMetaNodeModel>();
	//private FastSet list = new FastSet();
	/*private FastMap<gxtComponentControllerMetaNodeModel> map = new FastMap<gxtComponentControllerMetaNodeModel>();
	
	
	public FastMap<gxtComponentControllerMetaNodeModel> getMap() {
		return map;
	}

	public void setMap(FastMap<gxtComponentControllerMetaNodeModel> map) {
		this.map = map;
	}*/

	@Column(nullable=false,unique=true)
	public String getControllerMetaModelId() {
		return super.get(MetaDataConstants.COMPONENT_CONTROLLER_METAMODEL_ID);
//		return controllerMetaModelId;
	}

	public void setControllerMetaModelId(String controllerMetaModelId) {
		super.set(MetaDataConstants.COMPONENT_CONTROLLER_METAMODEL_ID, controllerMetaModelId);
//		this.controllerMetaModelId = controllerMetaModelId;
	}
	
	
	//@Transient
	@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
	//@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="componentControllerMetaModel_id")
	//	@LazyCollection(LazyCollectionOption.FALSE)
	@IndexColumn(name="ControllerMetaNodeModel_list_index")
	public List<GxtComponentControllerMetaNodeModel> getList() {
//		return list;
		return get(MetaDataConstants.GXT_COMPONENT_CONTROLLER_METANODEMODEL_LIST);
	}
	
	public void setList(List<GxtComponentControllerMetaNodeModel> list) {
//		this.list = list;
		set(MetaDataConstants.GXT_COMPONENT_CONTROLLER_METANODEMODEL_LIST,list);

	}
	
	public void add(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
//		this.list = list;
		getList().add(gxtComponentControllerMetaNodeModel);

	}
	
	/*@Id
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}*/
	
	
	
	/**
	 * 构造函数
	 */
	/*public GxtComponentMetaModel (FastMap<gxtComponentControllerMetaNodeModel> map  )
	{	
		super();
		this.setMap(map);
		for (String key : map.keySet()) {
			//System.err.println("List is" +this.getList());
			this.getList().add(map.get(key));
		}
	}*/
	
	protected void initList() {
		
	}

	
	@Transient
	@ServerOnly
	public GxtMetaModelTypeEnum getGxtControllerMetaModelTypeEnum() {
		if (getList().size()==1) {
			return GxtMetaModelTypeEnum.BASE_GXT_CONTROLLER_META_MODEL_TYPE;
		} else {
			return GxtMetaModelTypeEnum.TREE_GXT_CONTROLLER_META_MODEL_TYPE;
		}
	}
	
	
	public int indexOf(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
		return getList().indexOf(gxtComponentControllerMetaNodeModel);
	}
	/**
	 * 
	 * <ul>
	 * <li>方法含义：基于嵌套集合（先序遍历），得到当期节点在先序遍历方式洗的下一个节点</li>
	 * <li>方法作者：花宏宇</li>
	 * <li>编写日期：2010-8-29；时间：下午下午05:35:41</li>
	 * </ul>
	 * <ul>
	 * <b>修订编号：</b>
	 * <li>修订日期：</li>
	 * <li>修订作者：</li>
	 * <li>修订原因：</li>
	 * <li>修订内容：</li>
	 * </ul>
	 * @param gxtComponentMetaNodeModel
	 * @return
	 */
	@ServerOnly
	@Transient
	public GxtComponentControllerMetaNodeModel getNextNode(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
		int index = getList().indexOf(gxtComponentControllerMetaNodeModel);
		if (index<getList().size()-1) {
			return getList().get(index+1);
		} else {
			return null;
		}
		
		
	}
	
	

	@ServerOnly
	@Transient
	public int getChildCount(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
		return this.getChildren(gxtComponentControllerMetaNodeModel).size();
	}

	/**
	 * 
	 * <ul>
	 * <li>方法含义：获得当前节点的所有直接子节点（通过算法，可以直接计算出子节点，而不用遍历list）</li>
	 * <li>方法作者：花宏宇</li>
	 * <li>编写日期：2010-8-29；时间：下午上午10:24:35</li>
	 * </ul>
	 * <ul>
	 * <b>修订编号：</b>
	 * <li>修订日期：</li>
	 * <li>修订作者：</li>
	 * <li>修订原因：</li>
	 * <li>修订内容：</li>
	 * </ul>
	 * @param gxtComponentMetaNodeModel
	 * @return
	 */
	@Transient
	@ServerOnly
	public List<GxtComponentControllerMetaNodeModel> getChildren(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
		//TODO 需要实现获取所有直接节点
		return null;
	}

	@Transient
	@ServerOnly
	public GxtComponentControllerMetaNodeModel getParent(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
		//方法1
		GxtComponentControllerMetaNodeModel tempNodeModel = null;
		for (GxtComponentControllerMetaNodeModel parentnode : getList()) {
			if ((gxtComponentControllerMetaNodeModel.getLeftValue()-1)==parentnode.getLeftValue()
					&&(gxtComponentControllerMetaNodeModel.getLeftValue()+1)==parentnode.getLeftValue()) {
				tempNodeModel = parentnode;
				return tempNodeModel;

			}
			if (gxtComponentControllerMetaNodeModel.getLeftValue()>parentnode.getLeftValue()&&
					gxtComponentControllerMetaNodeModel.getRightValue()<parentnode.getRightValue()) {
				tempNodeModel = parentnode;
			}
		}
		return tempNodeModel;
		/*//方法2
		GxtComponentMetaNodeModel tempNodeModel = null;
		int index = this.indexOf(gxtComponentMetaNodeModel);
		for (int i = 0; i < index; i++) {
			if (gxtComponentMetaNodeModel.getLeftValue()<list.get(i).getLeftValue()&&
					gxtComponentMetaNodeModel.getLeftValue()<list.get(i).getRightValue()) {
				tempNodeModel = gxtComponentMetaNodeModel;
			}
			
		}
		return tempNodeModel;
		//方法3
		GxtComponentMetaNodeModel tempNodeModel = null;
		int index = this.indexOf(gxtComponentMetaNodeModel);
		for (int i = index-1; i >=0 ; --i) {
			if (gxtComponentMetaNodeModel.getLeftValue()<list.get(i).getLeftValue()&&
					gxtComponentMetaNodeModel.getLeftValue()<list.get(i).getRightValue()) {
				tempNodeModel = gxtComponentMetaNodeModel;
				return tempNodeModel;
			}
			
		}*/
		
		
	}
	
	/**
	 * 
	 * <ul>
	 * <li>方法含义：获取树形结构（嵌套集合）的根节点</li>
	 * <li>方法作者：花宏宇</li>
	 * <li>编写日期：2010-8-29；时间：下午上午09:50:44</li>
	 * </ul>
	 * <ul>
	 * <b>修订编号：</b>
	 * <li>修订日期：</li>
	 * <li>修订作者：</li>
	 * <li>修订原因：</li>
	 * <li>修订内容：</li>
	 * </ul>
	 * @return
	 */
	@Transient
	@ServerOnly
	public GxtComponentControllerMetaNodeModel getRoot() {
		if(getList().get(0).getLeftValue()!=1){
			throw new RuntimeException(
					"GxtComponentControllerMetaNodeModel的List<GxtComponentControllerMetaNodeModel>的第一个元素，非法！");
		}
		return getList().get(0);
		
	}	
	
	/**
	 * 
	 * <ul>
	 * <li>方法含义：判断当前节点是否为叶子节点</li>
	 * <li>方法作者：花宏宇</li>
	 * <li>编写日期：2010-8-30；时间：下午上午10:15:55</li>
	 * </ul>
	 * <ul>
	 * <b>修订编号：</b>
	 * <li>修订日期：</li>
	 * <li>修订作者：</li>
	 * <li>修订原因：</li>
	 * <li>修订内容：</li>
	 * </ul>
	 * @param gxtComponentControllerMetaNodeModel
	 * @return
	 */
	public boolean isLeaf(GxtComponentControllerMetaNodeModel gxtComponentControllerMetaNodeModel) {
		if (gxtComponentControllerMetaNodeModel.getLeftValue()+1==gxtComponentControllerMetaNodeModel.getRightValue()) {
			return true;
		} else {
			return false;
		}
		
	}
	
	
	

	/*@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="rpcModel_id")
	@LazyCollection(LazyCollectionOption.FALSE)
	public Set<GwtRpcModel> getModels() {
//		return models;
		return get("models");
	}
	
	public void setModels(Set<GwtRpcModel> models) {
//		this.models = models;
		set("models", models);
	}*/
		
	
	
	
}
